using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Xsl;
using System.IO;
using System.Diagnostics;


namespace BadHabit.Factory {


    public partial class Factory {




        #region TableAdapters

        private  Data.ProjectDataSetTableAdapters.ProjectTableAdapter projectTA = new BadHabit.Factory.Data.ProjectDataSetTableAdapters.ProjectTableAdapter();
                
        private Data.ProjectDataSetTableAdapters.ProjectRoleTableAdapter projectRoleTA = new BadHabit.Factory.Data.ProjectDataSetTableAdapters.ProjectRoleTableAdapter();
        

        
        private Data.ProjectDataSetTableAdapters.BacklogItemTableAdapter backlogItemTA = new BadHabit.Factory.Data.ProjectDataSetTableAdapters.BacklogItemTableAdapter();
        private Data.ProjectDataSetTableAdapters.BacklogItemUnitTableAdapter backlogItemUnitTA = new BadHabit.Factory.Data.ProjectDataSetTableAdapters.BacklogItemUnitTableAdapter();
        private Data.ProjectDataSetTableAdapters.BacklogItemHoursTableAdapter backlogItemHoursTA = new BadHabit.Factory.Data.ProjectDataSetTableAdapters.BacklogItemHoursTableAdapter();

        private  Data.ProjectDataSetTableAdapters.SprintTableAdapter sprintTA = new BadHabit.Factory.Data.ProjectDataSetTableAdapters.SprintTableAdapter();
        private Data.ProjectDataSetTableAdapters.SprintCodeVersionTableAdapter sprintCodeVersionTA = new BadHabit.Factory.Data.ProjectDataSetTableAdapters.SprintCodeVersionTableAdapter();

        

        private  Data.ProjectDataSetTableAdapters.QueriesTableAdapter queriesTA = new BadHabit.Factory.Data.ProjectDataSetTableAdapters.QueriesTableAdapter();

        // Proposals TAs
        private  Data.ProjectDataSetTableAdapters.ProposalTableAdapter proposalTA = new BadHabit.Factory.Data.ProjectDataSetTableAdapters.ProposalTableAdapter();
        private Data.ProjectDataSetTableAdapters.ProposalApprovedTableAdapter proposalApprovedTA = new BadHabit.Factory.Data.ProjectDataSetTableAdapters.ProposalApprovedTableAdapter();
        private Data.ProjectDataSetTableAdapters.ProposalItemTableAdapter proposalItemTA = new BadHabit.Factory.Data.ProjectDataSetTableAdapters.ProposalItemTableAdapter();        
        private  Data.ProjectDataSetTableAdapters.ProposalObservationTableAdapter proposalObservationsTA = new BadHabit.Factory.Data.ProjectDataSetTableAdapters.ProposalObservationTableAdapter();
        private  Data.ProjectDataSetTableAdapters.ProposalFixedCostItemTableAdapter proposalFixedCostItemTA = new BadHabit.Factory.Data.ProjectDataSetTableAdapters.ProposalFixedCostItemTableAdapter();
        private  Data.ProjectDataSetTableAdapters.ProjectPaymentTableAdapter projectPaymentTA = new BadHabit.Factory.Data.ProjectDataSetTableAdapters.ProjectPaymentTableAdapter();


        private Data.ProjectPerformanceDataSetTableAdapters.ProjectPerformanceTableAdapter performanceTA = new BadHabit.Factory.Data.ProjectPerformanceDataSetTableAdapters.ProjectPerformanceTableAdapter();


        private Data.ProjectDataSetTableAdapters.RiskTableAdapter riskTA = new BadHabit.Factory.Data.ProjectDataSetTableAdapters.RiskTableAdapter();
        
        #endregion



        private const string APPLICATION_LOGNAME = "Factory Server";

        private static string serverFilePath;
        private static string serverUrl;

        private static Factory currentFactory = null;

        public static void CreateFactory(string serverFilePath, string serverUrl) {
            if (currentFactory != null)
                return;
            currentFactory = new Factory(serverFilePath, serverUrl);
        }

        public static Factory Current {
            get {
                if (currentFactory == null)
                    throw new Exception("Factory was not created.");
                return currentFactory;
            }
        }

        public string UserCulture {
            get;
            set;
        }
        
        /// <summary>
        /// Creates a factory at the given server path.
        /// </summary>
        /// <param name="serverPath">The server url</param>
        private Factory(string serverFilePath, string serverUrl) {

            Factory.serverFilePath = serverFilePath;
            Factory.serverUrl = serverUrl;

            
            LoadTeamMembers();



                     

            proposalObservationsTA.ClearBeforeFill = false;
            proposalItemTA.ClearBeforeFill = false;
            proposalFixedCostItemTA.ClearBeforeFill = false;            
        }

    

        public static string ServerUrl {
            get {
                return serverUrl;
            }
        }

        public static string ServerPath {
            get {
                return serverFilePath;
            }
        }

      

        

        /// <summary>
        /// Approves the proposal.
        /// </summary>
        /// <param name="user">User approving the proposal</param>
        /// <param name="project">Project that should be approved</param>
        public Data.ProjectDataSet ApproveProposal(Data.ProjectDataSet project, string proposalUId, out string alertMessage) {
            Data.ProjectDataSet.ProposalRow proposal = project.Proposal.FindByProposalUId(proposalUId);
            if (proposal == null)
                throw new Exception("Could not find the proposal to approve it.");

            // Set approval date and status
            proposal.ApprovalDate = DateTime.Now;            
            SetProposalStatus(proposal, project.Project[0], ProposalStatus.PROPOSAL_APPROVED);

            SaveProposalApprovedXAML(proposal);
         
            return PrepareToSaveProject(project, out alertMessage);
        }

        private void SaveProposalApprovedXAML(Data.ProjectDataSet.ProposalRow proposal) {
            Reports.ProposalReport report = new Reports.ProposalReport(this, proposal.ProposalUId);

            Data.ProjectDataSet dsProject = proposal.Table.DataSet as Data.ProjectDataSet;

            string proposalXaml = report.GenerateFlowDocumentXAML(dsProject, proposal.TemplateName);
            dsProject.ProposalApproved.AddProposalApprovedRow(proposal, proposal.ProjectUId, proposalXaml);

        }

        public string RetriveApprovedProposalXaml(string proposalUId) {
            Data.ProjectDataSet dsProject = new BadHabit.Factory.Data.ProjectDataSet();
            dsProject.EnforceConstraints = false;
            proposalApprovedTA.FillByProposalUId(dsProject.ProposalApproved, proposalUId);
            if (dsProject.ProposalApproved.Count == 0)
                return null;

            return dsProject.ProposalApproved[0].ProposalXAML;
        }

        /// <summary>
        /// Rejects a Proposal.
        /// </summary>
        /// <param name="user">User sending the proposal</param>
        /// <param name="project">Project</param>
        public Data .ProjectDataSet RejectProposal(Data.ProjectDataSet project, string proposalUId, out string alertMesssage) {
            Data.ProjectDataSet.ProposalRow proposal = project.Proposal.FindByProposalUId(proposalUId);
            if (proposal == null)
                throw new Exception("Could not find the proposal to reject it.");

            proposal.ApprovalDate = DateTime.Now;            
            SetProposalStatus(proposal, project.Project[0], ProposalStatus.PROPOSAL_REJECTED);

            SaveProposalApprovedXAML(proposal);

            return PrepareToSaveProject(project, out alertMesssage);
        }

        /// <summary>
        /// Update the proposal and the project with the given status.
        /// Note that the project status is not always equal to the proposal, it
        /// is calculed based on all proposal status.
        /// </summary>
        /// <param name="proposal">The proposal row</param>
        /// <param name="status">The new status</param>
        private void SetProposalStatus(Data.ProjectDataSet.ProposalRow proposal, Data.ProjectDataSet.ProjectRow project, ProposalStatus status) {
            Data.ProjectDataSet ds = (Data.ProjectDataSet)proposal.Table.DataSet;
            
            if (project == null)
                throw new Exception("Could not find the project of the proposal");
            
            // set the proposal status
            proposal.Status = (short)status;

            if (project.Status == (short)ProjectStatus.PROJECT_STARTED)
                return;

            // Now set the project status
                        
            int totalCount = ds.Proposal.Rows.Count;
            int waintingCount = Int32.Parse(ds.Proposal.Compute("count(proposalUId)", "Status=" + (short)ProposalStatus.PROPOSAL_WAITING).ToString());
            int approvedCount = Int32.Parse(ds.Proposal.Compute("count(proposalUId)", "Status=" + (short)ProposalStatus.PROPOSAL_APPROVED).ToString());
            int rejectCount = Int32.Parse(ds.Proposal.Compute("count(proposalUId)", "Status=" + (short)ProposalStatus.PROPOSAL_REJECTED).ToString());

            // if all the proposal were rejected, so is the project
            if (rejectCount == totalCount)
                project.Status = (short) ProjectStatus.PROPOSAL_REJECTED;

            // if is there at least one waiting, so is the project
            if (waintingCount > 0)
                project.Status = (short)ProjectStatus.PROPOSAL_WAITING;

            // if is there no wainting, but at least one approved, so is approved the project
            if (approvedCount > 0) 
                project.Status = (short)ProjectStatus.PROPOSAL_APPROVED;
            
        }
        




        private void RunCreateHook(Data.ProjectDataSet project) {
            string hookPath = ServerPath + @"\App_Data\ProjectTemplates\" + project.Project[0].Category + @"\Hooks\CreateProject.bat";
            string args = "\"" + project.Project[0].ClientName + "\" \"" + project.Project[0].ProjectName + "\" \"";

            System.Diagnostics.ProcessStartInfo psi = new ProcessStartInfo(hookPath, args);
            
            psi.CreateNoWindow = true;
            psi.UseShellExecute = true;
                                                                       
            System.Diagnostics.Process p = new Process();            
            p.StartInfo = psi;
            try {                
                p.Start();
            } catch (Exception ex) {
                LogError(ex);
                return;
            }
            
            p.WaitForExit();
            
            if(p.ExitCode!=0)
                LogError(null, "CreateProject.Bat exit with error " +  p.ExitCode);

        }


        /// <summary>
        /// Need to make sure that only the VerifiedBy and VerifiedDate columns from
        /// BacklogItem table is changed when is a Quality Assurance Role that is saving.
        /// </summary>
        /// <param name="project"></param>
        /// <returns></returns>
        private Data.ProjectDataSet RestrictQualityAssuranceSave(Data.ProjectDataSet project) {

            // just backlog items
            Data.ProjectDataSet dsOnlyItems = new BadHabit.Factory.Data.ProjectDataSet();
            dsOnlyItems.Merge(project.Project);
            dsOnlyItems.Merge(project.BacklogItem);

            dsOnlyItems.Project[0].RejectChanges();

            // revert all columns to original itens, except the verified By and Date
            for(int i=0; i<dsOnlyItems.BacklogItem.Count; i++) {
                foreach (System.Data.DataColumn c in dsOnlyItems.BacklogItem.Columns) {
                    if(!c.Equals(dsOnlyItems.BacklogItem.VerifiedByColumn) && !c.Equals(dsOnlyItems.BacklogItem.VerifiedDateColumn))
                        dsOnlyItems.BacklogItem[i][c.ColumnName] = dsOnlyItems.BacklogItem[i][c.ColumnName, System.Data.DataRowVersion.Original];
                }
            }

            return dsOnlyItems;
          
            
        }

        /// <summary>
        /// Saves the project.
        /// </summary>
        /// <param name="project">project to be saved</param>
        public Data.ProjectDataSet PrepareToSaveProject(Data.ProjectDataSet project, out string alertMessage) {
            alertMessage = null;

            if (!CurrentTeamMemberPrincipal.IsInRole(TeamRoles.SCRUM_MASTER.ToString()))
                project = RestrictQualityAssuranceSave(project);
            

            if (project.Project.Count > 0) {

                // if it's a new project
                if (project.Project[0].RowState == System.Data.DataRowState.Added) {                                        
                    project.Project[0].Status = (short)ProjectStatus.PROPOSAL_CREATION; // sets project status
                    project.Project[0].ProjectOwner = CurrentTeamMember;
                    if(project.Project[0].IsProjectDocBaseNull())
                        project.Project[0].ProjectDocBase = CalcsProjectDocBasePath(project);
                    
                    RunCreateHook(project);

                }                
            }

            
            // save its now
            Data.ProjectDataSet savedProject = null;
            try {                
                savedProject = SaveProject(project);
            }   
            catch (System.Data.DBConcurrencyException) {
                alertMessage = "CONCURRENCY_SAVE_ERROR";
                return null;
            } catch (System.Data.SqlClient.SqlException sqlEx) {
                if (sqlEx.Number == 547) {
                    alertMessage = "CONSTRAINT_SAVE_ERROR";
                    return null;
                }
                throw sqlEx;
            }
            
            SendSaveProjectEmails(savedProject);

            return savedProject;
        }

        public void SendSaveProjectEmails(Data.ProjectDataSet project) {

            if (project.Project.Count == 0)
                return;

            ProjectEmailMessage msg = new ProjectEmailMessage(project.Project[0].ProjectUId, ServerPath, ServerUrl);

            // if project has changed its status
            if (project.Project[0].RowState.Equals(System.Data.DataRowState.Added) ||
                !project.Project[0].Status.Equals(project.Project[0]["Status", System.Data.DataRowVersion.Original])) {            
                try {                
                    msg.SendStatusChangeNotification();
                } catch (Exception ex) {
                    LogError(ex);
                }
            }

            // if project has changed its baseline
            if (project.Project[0].RowState.Equals(System.Data.DataRowState.Added) ||
                !project.Project[0].Baseline.Equals(project.Project[0]["Baseline", System.Data.DataRowVersion.Original])) {            
                try {                
                    msg.SendNewPlanNotification();
                } catch (Exception ex) {
                    LogError(ex);
                }
            }

            // if project has new members
            Data.ProjectDataSet.ProjectRoleRow[] newMembers = (Data.ProjectDataSet.ProjectRoleRow[]) project.ProjectRole.Select("", "", System.Data.DataViewRowState.Added);
            if (project.Project[0].RowState.Equals(System.Data.DataRowState.Added) || 
                newMembers.Length > 0) {
                try {
                    msg.SendNewMemberNotification(newMembers);
                } catch (Exception ex) {
                    LogError(ex);
                }
            }

        }




        /// <summary>
        /// Calcs the project doc base for a given project.
        /// </summary>
        /// <param name="project">Project</param>
        /// <returns>doc base path</returns>
        public string CalcsProjectDocBasePath(Data.ProjectDataSet project) {
            return Properties.Settings.Default.DocumentRepositoryPath + "\\" + project.Project[0].ClientName + "\\" + project.Project[0].ProjectName;
        }
       

        /// <summary>
        /// Retrives the project template list that are saved at the root path.
        /// </summary>
        /// <param name="rootPath">Root Path</param>
        /// <returns>Name of the project templates</returns>
        public String[] RetriveProjectTemplateList(string rootPath) {
            String[] list = System.IO.Directory.GetDirectories(rootPath);
            for (int i = 0; i < list.Length; i++)
                list[i] = list[i].Substring(list[i].LastIndexOf("\\") + 1);
            return list;
        }


        public Data.ProjectDataSet RetriveSprintDefaultItems(string projectCategory) {
            // read the project from the XML template file
            Data.ProjectDataSet dsTemplate = new Data.ProjectDataSet();
            dsTemplate.EnforceConstraints = false;
            dsTemplate.ReadXml(ServerPath + "\\App_Data\\ProjectTemplates\\" + projectCategory + "\\SprintData.xml");
            return dsTemplate;
        }


        public Data.ProjectDataSet RetriveBacklogItemUnits() {
            Data.ProjectDataSet dsProject = new BadHabit.Factory.Data.ProjectDataSet();
            dsProject.EnforceConstraints = false;
            backlogItemUnitTA.FillDistinct(dsProject.BacklogItemUnit);
            return dsProject;
        }
    
      


        /// <summary>
        /// Retrives the project template.
        /// </summary>
        /// <param name="templatePath">Path where the template files are stored</param>
        /// <returns>Template</returns>
        public Data.ProjectDataSet RetriveProjectTemplate(string templatePath) {
            
            // read the project from the XML template file
            Data.ProjectDataSet dsTemplate = new Data.ProjectDataSet();
            dsTemplate.ReadXml(templatePath + "\\ProjectData.xml");

            // Fix the project Number
            dsTemplate.Project[0].ProjectNumber = NextProjectNumber();

            // Fix the estimated start date
            dsTemplate.Project[0].EstimatedStartDate = DateTime.Today;
            
            // ok, now we need to fix the Guid ids            
            String projectUId = Guid.NewGuid().ToString().ToLower();
            dsTemplate.EnforceConstraints = false;

            foreach (Data.ProjectDataSet.ProjectRow r in dsTemplate.Project.Rows)
                r.ProjectUId = projectUId;

            foreach (Data.ProjectDataSet.SprintRow r in dsTemplate.Sprint.Rows) {
                r.SprintUId = Guid.NewGuid().ToString().ToLower();
                r.ExpirationDate = DateTime.Now.AddDays(31);
                r.CreateDate = DateTime.Now;                
            }

            foreach (Data.ProjectDataSet.BacklogItemRow r in dsTemplate.BacklogItem.Rows)
                r.BacklogItemUId = Guid.NewGuid().ToString().ToLower();

            foreach (Data.ProjectDataSet.BacklogItemHoursRow r in dsTemplate.BacklogItemHours.Rows)
                r.BacklogItemHoursUId = Guid.NewGuid().ToString().ToLower();

            dsTemplate.Project[0].CreateDate = DateTime.Now;

            if (dsTemplate.Project[0].HourBankMode == (short)HourBankMode.NOT_BANKPROJECT) {
                Data.ProjectDataSet dsSprint = RetriveSprintDefaultItems(dsTemplate.Project[0].Category);
                dsTemplate.Project[0].AddNewSprint(dsSprint);
            }

         
            dsTemplate.EnforceConstraints = true;

            return dsTemplate;
        }

        /// <summary>
        /// Retrives the proposal template.
        /// </summary>
        /// <param name="templatePath">Path where the template files are stored</param>
        /// <returns>Template</returns>
        public Data.ProjectDataSet RetriveProposalTemplate(string templatePath) {

            // read the project from the XML template file
            Data.ProjectDataSet dsTemplate = new Data.ProjectDataSet();
            dsTemplate.EnforceConstraints = false;
            dsTemplate.ReadXml(templatePath + "\\ProposalData.xml");
            
            // Fix the create date
            dsTemplate.Proposal[0].CreateDate = DateTime.Now;

            // ok, now we need to fix the Guid ids            
            String proposalUId = Guid.NewGuid().ToString().ToLower();
            

            foreach (Data.ProjectDataSet.ProposalRow r in dsTemplate.Proposal.Rows)
                r.ProposalUId = proposalUId;

            foreach (Data.ProjectDataSet.ProposalObservationRow r in dsTemplate.ProposalObservation.Rows)
                r.ProposalObservationUId = Guid.NewGuid().ToString().ToLower();

            foreach (Data.ProjectDataSet.ProposalFixedCostItemRow r in dsTemplate.ProposalFixedCostItem.Rows)
                r.FixedPriceItemUId = Guid.NewGuid().ToString().ToLower();

            return dsTemplate;
        }


       

        

        /// <summary>
        /// Retrives the e-mail that should be send to the client.
        /// </summary>
        /// <param name="project">Project</param>        
        /// <returns>The email body and subject</returns>
        public Data.EmailDataSet RetriveTemplateEmail(string projectUId, string templatePath) {

            Data.ProjectDataSet project = RetriveProject(projectUId);
                        
            // read the project from the XML template file
            Data.EmailDataSet dsTemplate = new Data.EmailDataSet();
            dsTemplate.ReadXml(serverFilePath + ".\\Templates\\" + project.Project[0].Category + "\\" + templatePath);
            dsTemplate.Email[0].Subject = dsTemplate.Email[0].Subject.Replace("$ProjectName$", project.Project[0].ProjectName);
            dsTemplate.Email[0].Subject = dsTemplate.Email[0].Subject.Replace("$ClientName$", project.Project[0].ClientName);
            dsTemplate.Email[0].Body = dsTemplate.Email[0].Body.Replace("$ProjectName$", project.Project[0].ProjectName);
            dsTemplate.Email[0].Body = dsTemplate.Email[0].Body.Replace("$ClientName$", project.Project[0].ClientName);

            if (dsTemplate.Email[0].IsToNull())
                dsTemplate.Email[0].To = "";

            dsTemplate.Email[0].To = ProposalDestinataries(project) + dsTemplate.Email[0].To;

            return dsTemplate;
        }

        private string ProposalDestinataries(Data.ProjectDataSet project) {

            
            string emails = "";
            foreach (Data.ProjectDataSet.BacklogItemUnitRow unit in project.BacklogItemUnit.Select("Type=" + (short)TeamRoles.CLIENT_CONTACT)) {
                foreach (Data.ProjectDataSet.ProjectRoleRow r in project.ProjectRole.Select("UnitName='" + unit.UnitName + "'" ))
                    emails = emails + r.ContactEmail + ";";                 
            }
            return emails;
            
        }



       




       

       

      


   


        public static bool CheckVersion(string version) {
            if ("unknow/debug".Equals(version))
                return true;

            if ("factoryTail".Equals(version))
                return true;

            if ("factoryWebSite".Equals(version))
                return true;

            Int64 v =0;
            Int64 vo = 0;
            try {
                v = Int64.Parse(version.Replace(".", ""));
                vo = Int64.Parse(Properties.Settings.Default.FactoryClientMinVersion.Replace(".", ""));
            }
            catch (Exception) {
                return false;
            }

            if (v < vo)
                return false;

            return true;
            
        }

         




        /*********************************************************************************/


        


        /// <summary>
        /// Store the project dataset into the data base.
        /// </summary>
        /// <param name="project">project dataset</param>
        public Data.ProjectDataSet SaveProject(Data.ProjectDataSet project) {


     

            UpdateRoleMemberInformation(project);

            Data.ProjectDataSet deletedRows = (Data.ProjectDataSet)project.GetChanges(System.Data.DataRowState.Deleted);
            Data.ProjectDataSet modifiedRows = (Data.ProjectDataSet)project.GetChanges(System.Data.DataRowState.Modified);
            Data.ProjectDataSet addedModifiedRows = (Data.ProjectDataSet)project.GetChanges(System.Data.DataRowState.Added);

            if (modifiedRows != null) {
                if (addedModifiedRows == null)
                    addedModifiedRows = modifiedRows;
                else
                    addedModifiedRows.Merge(modifiedRows);
            }

            // child tables deletes
            if (deletedRows != null) {

                riskTA.Update(deletedRows);

                proposalApprovedTA.Update(deletedRows);
                proposalItemTA.Update(deletedRows);  
                proposalFixedCostItemTA.Update(deletedRows);
                proposalObservationsTA.Update(deletedRows);

                projectPaymentTA.Update(deletedRows);
                

                backlogItemHoursTA.Update(deletedRows);   // scanerio childs

                backlogItemTA.Update(deletedRows);     // release childs

                proposalTA.Update(deletedRows);    // project childs
                sprintTA.Update(deletedRows);
                projectRoleTA.Update(deletedRows);
                backlogItemUnitTA.Update(deletedRows);

                projectTA.Update(deletedRows); // project                

            }

            if (addedModifiedRows != null) {

                // parent table updates            
                projectTA.Update(addedModifiedRows);

                backlogItemUnitTA.Update(addedModifiedRows);

                projectRoleTA.Update(addedModifiedRows);

                // did that cuz this thing is nothing working at design time
                addedModifiedRows.BacklogItem.ParentRelations[0].ChildKeyConstraint.AcceptRejectRule = System.Data.AcceptRejectRule.None;

                sprintTA.Update(addedModifiedRows);
                

                backlogItemTA.Update(addedModifiedRows);

                backlogItemHoursTA.Update(addedModifiedRows);

                proposalTA.Update(addedModifiedRows);

                proposalItemTA.Update(addedModifiedRows);   // proposal childs  
                proposalFixedCostItemTA.Update(addedModifiedRows);
                proposalObservationsTA.Update(addedModifiedRows);
                proposalApprovedTA.Update(addedModifiedRows);


                projectPaymentTA.Update(addedModifiedRows);

                riskTA.Update(addedModifiedRows);

            }

            return project;

        }

        /// <summary>
        /// Return the next project number.
        /// </summary>
        /// <returns>next project number</returns>
        public  short NextProjectNumber() {
            int? num = (int?) projectTA.ScalarMaxProjectNumber();
            if (!num.HasValue)
                return 0;
            return (short)(num.Value + 1);
        }



        public Data.ProjectDataSet RetriveProjectWithOutProposal(string projectUId) {
            Data.ProjectDataSet project = new BadHabit.Factory.Data.ProjectDataSet();
            FillProjectDateSet(projectUId, project, true, true, true, false, true);
            return project;
        }


        public Data.ProjectDataSet RetriveProjectAndRolesOnly(string projectUId) {
            Data.ProjectDataSet project = new BadHabit.Factory.Data.ProjectDataSet();
            FillProjectDateSet(projectUId, project, true, true, false, false, false);
            return project;
        }

        public  Data.ProjectDataSet RetriveProject(string projectUId) {
            Data.ProjectDataSet project = new BadHabit.Factory.Data.ProjectDataSet();
            FillProjectDateSet(projectUId, project, true, true, true, true, true);
            return project;
        }

        public Data.ProjectDataSet RetriveProject(int projectNumber) {
            Data.ProjectDataSet project = new BadHabit.Factory.Data.ProjectDataSet();
            projectTA.FillByProjectNumber(project.Project, projectNumber);
            FillProjectDateSet(project.Project[0].ProjectUId, project, false, true, true, true, true);
            return project;
        }
                
        /// <summary>
        /// Fills a project dataset with data from the databae.
        /// </summary>
        /// <param name="projectUId">The projectUId</param>
        /// <param name="project">The dataset project to be filled</param>
        /// <param name="fillProject">True if the project table should be filled</param>
        /// <param name="fillRoles">True if the role table should be filled</param>
        /// <param name="fillBacklog">True if the backlogs tables should be filled</param>
        /// <param name="fillProposal">Thrue if the proposals tables should be filled</param>
        private void FillProjectDateSet(string projectUId, Data.ProjectDataSet project, bool fillProject, bool fillRoles, bool fillBacklog, bool fillProposal, bool fillRisk) {

            if(fillProject)
                projectTA.FillByProjectUId(project.Project, projectUId);

            if (fillRoles) {
                backlogItemUnitTA.FillByProjectUId(project.BacklogItemUnit, projectUId);
                projectRoleTA.FillByProjectUId(project.ProjectRole, projectUId);
            }

            if (fillBacklog) {
                sprintTA.FillByProjectUId(project.Sprint, projectUId);
                backlogItemTA.FillByProjectUId(project.BacklogItem, projectUId);
                backlogItemHoursTA.FillByProjectUId(project.BacklogItemHours, projectUId);
                sprintCodeVersionTA.FillByProjectUId(project.SprintCodeVersion, projectUId);
            }
                        
            if(System.Threading.Thread.CurrentPrincipal.IsInRole(TeamRoles.COMMERCIAL_GUY.ToString())) {
                if (fillProposal) {
                    proposalTA.FillByProjectUId(project.Proposal, projectUId);
                    projectPaymentTA.FillByProjectUId(project.ProjectPayment, projectUId);

                    foreach (Data.ProjectDataSet.ProposalRow p in project.Proposal) {
                        proposalObservationsTA.FillByProposalUId(project.ProposalObservation, p.ProposalUId);
                        proposalFixedCostItemTA.FillByProposalUId(project.ProposalFixedCostItem, p.ProposalUId);
                        proposalItemTA.FillByProposalUId(project.ProposalItem, p.ProposalUId);                    
                    }
                }
            }

            if (fillRisk) {
                riskTA.FillByProjectUId(project.Risk, projectUId);
            }


        }


        /// <summary>
        /// Retrive all projects from the data base.
        /// </summary>        
        /// <returns>project dataset</returns>
        public  Data.ProjectDataSet RetriveAllProjects() {
            Data.ProjectDataSet project = new BadHabit.Factory.Data.ProjectDataSet();
            projectTA.Fill(project.Project);

            return project;
        }

        /// <summary>
        /// Retrive oportunities projects.
        /// </summary>        
        /// <returns>project dataset</returns>
        public  Data.ProjectDataSet RetriveOportunitiesProjects() {
            Data.ProjectDataSet project = new BadHabit.Factory.Data.ProjectDataSet();
            projectTA.FillOportunitiesProjects(project.Project);
            return project;
        }

        /// <summary>
        /// Retrive schdeuled projects.
        /// </summary>        
        /// <returns>project dataset</returns>
        public  Data.ProjectDataSet RetriveScheduledProjects() {
            Data.ProjectDataSet project = new BadHabit.Factory.Data.ProjectDataSet();
            projectTA.FillScheduledProjects(project.Project);
            return project;
        }

        /// <summary>
        /// Retrive running projects.
        /// </summary>        
        /// <returns>project dataset</returns>
        public  Data.ProjectDataSet RetriveRunningProjects() {
            Data.ProjectDataSet project = new BadHabit.Factory.Data.ProjectDataSet();
            projectTA.FillRunningProjects(project.Project);
            return project;
        }

        /// <summary>
        /// Retrive closed projects.
        /// </summary>        
        /// <returns>project dataset</returns>
        public  Data.ProjectDataSet RetriveClosedProjects() {
            Data.ProjectDataSet project = new BadHabit.Factory.Data.ProjectDataSet();
            projectTA.FillClosedProjects(project.Project);
            return project;
        }

        /// <summary>
        /// Retrive still to pay projects.
        /// </summary>        
        /// <returns>project dataset</returns>
        public Data.ProjectDataSet RetriveStillToPayProjects() {
            Data.ProjectDataSet project = new BadHabit.Factory.Data.ProjectDataSet();
            projectTA.FillStillToPayProjects(project.Project);
            return project;
        }

        /// <summary>
        /// Retrive in debit projects.
        /// </summary>        
        /// <returns>project dataset</returns>
        public Data.ProjectDataSet RetriveInDebitProjects() {
            Data.ProjectDataSet project = new BadHabit.Factory.Data.ProjectDataSet();
            projectTA.FillInDebitProjects(project.Project);
            return project;
        }


        /// <summary>
        /// Retrive closed projects.
        /// </summary>        
        /// <returns>project dataset</returns>
        public  Data.ProjectDataSet RetriveToDoProjects(string userUId) {
            Data.ProjectDataSet project = new BadHabit.Factory.Data.ProjectDataSet();
            projectTA.FillToDoProjects(project.Project, userUId);
            return project;
        }

        /// <summary>
        /// Retrive projects that the member is into.
        /// </summary>        
        /// <returns>project dataset</returns>
        public Data.ProjectDataSet RetriveTeamMemberProjects(string teamMemberId) {
            Data.ProjectDataSet project = new BadHabit.Factory.Data.ProjectDataSet();
            projectTA.FillByTeamMember(project.Project, teamMemberId);
            return project;
        }

        /// <summary>
        /// Retrive all projects that can be used as payable from the data base.
        /// </summary>        
        /// <returns>project dataset</returns>
        public  Data.ProjectDataSet RetriveAllPayableProjects() {
            Data.ProjectDataSet project = new BadHabit.Factory.Data.ProjectDataSet();
            projectTA.FillPayableProjects(project.Project);
            return project;
        }

        /// <summary>
        /// Retrive all models from the data base.
        /// </summary>        
        /// <returns>project model datatable</returns>
        public  Data.ProjectDataSet RetriveAllProjectModels() {
            Data.ProjectDataSet ds = new BadHabit.Factory.Data.ProjectDataSet();
            ds.EnforceConstraints = false;
            ds.ReadXml(ServerPath + "\\App_Data\\ProjectModels.xml");
            return ds;
        }

        /// <summary>
        /// Retrive all plataforms from the data base.
        /// </summary>        
        /// <returns>project plataforms datatable</returns>
        public  Data.ProjectDataSet RetriveAllProjectPlataforms() {
            Data.ProjectDataSet ds = new BadHabit.Factory.Data.ProjectDataSet();
            ds.ReadXml(ServerPath + "\\App_Data\\ProjectPlataforms.xml");
            return ds;
        }


        


  

        /// <summary>
        /// Retrive the factory team velocity for a given month.
        /// </summary>
        /// <param name="date">month</param>
        /// <returns>The velocity for the given month</returns>
        public  double RetriveFactoryTeamVelocity() {
            object o = queriesTA.ScalarFactoryTeamVelocity();
            if (o == null || o == DBNull.Value)
                return 0;
            return (double)o;
        }




        public static void LogWarnning(string message) {            
            try {
                System.IO.StreamWriter file = new StreamWriter(ServerPath + "\\App_Data\\Log\\factoryLog.txt", true);

                file.WriteLine("[" + DateTime.Now + "]: " + message);                
                file.WriteLine("--------------------------------------------------------------------------------------");
                file.Close();
            } catch (Exception) { }
        }



        public static void LogError(Exception e) {
            LogError(e, null);
        }

        public static void LogError(Exception e, string friendlyMsg) {

            string message = "";
            if (!String.IsNullOrEmpty(friendlyMsg))
                message = friendlyMsg + "\n";

            if(e!=null)
                message = message + e.Message;

            try {                
                System.IO.StreamWriter file = new StreamWriter(ServerPath + "\\App_Data\\Log\\factoryLog.txt", true);
                
                file.WriteLine("[" + DateTime.Now + "]: " + message);
                if (e != null) {
                    file.WriteLine("Source: " + e.Source);
                    file.WriteLine("Trace: " + e.StackTrace);
                }
                file.WriteLine("--------------------------------------------------------------------------------------");
                file.Close();                          
            }
            catch(Exception) {}

        }


        public Data.ProjectDataSet RetriveBacklogItemSizes() {
            Data.ProjectDataSet ds = new BadHabit.Factory.Data.ProjectDataSet();
            ds.ReadXml(ServerPath + "\\App_Data\\BacklogItemSizes.xml");
            return ds;

        }

        public Data.ProjectPerformanceDataSet.ProjectPerformanceRow RetriveProjectPerformanceIndicators(string projectUId) {
            Data.ProjectPerformanceDataSet dsPerformance = new BadHabit.Factory.Data.ProjectPerformanceDataSet();
            performanceTA.FillByProjectUId(dsPerformance.ProjectPerformance, projectUId);
            return dsPerformance.ProjectPerformance.FindByProjectUId(projectUId);
        }

        
        public string SourceControlViewUrl {
            get {
                return Properties.Settings.Default.SourceControlViewUrl;
            }
        }
        

        
    }
}
